package cn.drenal.capcap.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.drenal.capcap.entity.SysAdmin;
import cn.drenal.capcap.entity.SysAdminRole;
import cn.drenal.capcap.entity.SysRole;
import cn.drenal.capcap.entity.dto.AdminDTO;
import cn.drenal.capcap.entity.vo.AdminListVO;
import cn.drenal.capcap.exception.BizException;
import cn.drenal.capcap.mapper.SysAdminMapper;
import cn.drenal.capcap.mapper.SysAdminRoleMapper;
import cn.drenal.capcap.mapper.SysRoleMapper;
import cn.drenal.capcap.service.AdminService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import cn.dev33.satoken.secure.SaSecureUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.stream.Collectors;

/**
 * 管理员服务实现类
 */
@Service
@RequiredArgsConstructor
public class AdminServiceImpl extends ServiceImpl<SysAdminMapper, SysAdmin> implements AdminService {

    private final SysRoleMapper sysRoleMapper;
    private final SysAdminRoleMapper sysAdminRoleMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysAdmin createAdmin(AdminDTO adminDTO) {
        // 检查用户名是否已存在
        if (lambdaQuery().eq(SysAdmin::getUsername, adminDTO.getUsername()).exists()) {
            throw new BizException("用户名已存在");
        }

        // 创建管理员对象
        SysAdmin admin = new SysAdmin();
        admin.setUsername(adminDTO.getUsername());
        admin.setPassword(SaSecureUtil.md5(adminDTO.getPassword()));
        admin.setNickname(adminDTO.getNickname());
        admin.setAvatar(adminDTO.getAvatar());
        admin.setEmail(adminDTO.getEmail());
        admin.setPhone(adminDTO.getPhone());
        admin.setStatus(adminDTO.getStatus());

        // 设置角色，默认为普通管理员
        admin.setRole(adminDTO.getRole() != null ? adminDTO.getRole() : "admin");

        // 保存管理员
        save(admin);
        
        // 创建管理员-角色关联记录
        if (adminDTO.getRole() != null && !adminDTO.getRole().isEmpty()) {
            SysAdminRole adminRole = new SysAdminRole();
            adminRole.setUserId(admin.getId());
            
            // 根据角色编码查找对应的角色ID
            Long roleId = getRoleIdByCode(adminDTO.getRole());
            if (roleId != null) {
                adminRole.setRoleId(roleId);
                sysAdminRoleMapper.insert(adminRole);
            }
        }
        
        return admin;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysAdmin updateAdmin(Long id, AdminDTO adminDTO) {
        // 检查管理员是否存在
        SysAdmin admin = getById(id);
        if (admin == null) {
            throw new BizException("管理员不存在");
        }

        // 检查用户名是否被其他用户使用
        if (StringUtils.hasText(adminDTO.getUsername())
            && !admin.getUsername().equals(adminDTO.getUsername())
            && lambdaQuery().eq(SysAdmin::getUsername, adminDTO.getUsername()).exists()) {
            throw new BizException("用户名已存在");
        }

        // 更新管理员信息
        if (StringUtils.hasText(adminDTO.getUsername())) {
            admin.setUsername(adminDTO.getUsername());
        }
        if (StringUtils.hasText(adminDTO.getNickname())) {
            admin.setNickname(adminDTO.getNickname());
        }
        if (StringUtils.hasText(adminDTO.getAvatar())) {
            admin.setAvatar(adminDTO.getAvatar());
        }
        if (StringUtils.hasText(adminDTO.getEmail())) {
            admin.setEmail(adminDTO.getEmail());
        }
        if (StringUtils.hasText(adminDTO.getPhone())) {
            admin.setPhone(adminDTO.getPhone());
        }
        if (adminDTO.getStatus() != null) {
            admin.setStatus(adminDTO.getStatus());
        }
        
        // 更新角色
        if (StringUtils.hasText(adminDTO.getRole()) && !adminDTO.getRole().equals(admin.getRole())) {
            admin.setRole(adminDTO.getRole());
            
            // 更新管理员-角色关联记录
            // 先删除现有关联
            sysAdminRoleMapper.delete(
                new LambdaQueryWrapper<SysAdminRole>()
                    .eq(SysAdminRole::getUserId, id));
            
            // 添加新关联
            Long roleId = getRoleIdByCode(adminDTO.getRole());
            if (roleId != null) {
                SysAdminRole adminRole = new SysAdminRole();
                adminRole.setUserId(id);
                adminRole.setRoleId(roleId);
                sysAdminRoleMapper.insert(adminRole);
            }
        }

        // 保存更新
        updateById(admin);
        return admin;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAdmin(Long id) {
        // 检查是否为超级管理员
        if (!StpUtil.hasRole("super-admin")) {
            throw new BizException("无权限删除管理员");
        }

        // 删除管理员-角色关联记录
        sysAdminRoleMapper.delete(
            new LambdaQueryWrapper<SysAdminRole>()
                .eq(SysAdminRole::getUserId, id));
                
        // 检查管理员是否存在
        if (!removeById(id)) {
            throw new BizException("管理员不存在");
        }
    }

    @Override
    public Page<AdminListVO> getAdminList(Page<SysAdmin> page, String username, String nickname, String phone) {
        LambdaQueryWrapper<SysAdmin> wrapper = new LambdaQueryWrapper<>();

        // 添加查询条件
        if (StringUtils.hasText(username)) {
            wrapper.like(SysAdmin::getUsername, username);
        }
        if (StringUtils.hasText(nickname)) {
            wrapper.like(SysAdmin::getNickname, nickname);
        }
        if (StringUtils.hasText(phone)) {
            wrapper.like(SysAdmin::getPhone, phone);
        }

        // 执行分页查询
        Page<SysAdmin> adminPage = page(page, wrapper);

        // 转换为AdminListVO
        Page<AdminListVO> voPage = new Page<>(adminPage.getCurrent(), adminPage.getSize(), adminPage.getTotal());
        voPage.setRecords(adminPage.getRecords().stream().map(admin -> {
            AdminListVO vo = new AdminListVO();
            BeanUtils.copyProperties(admin, vo);
            SysRole role = sysRoleMapper.selectOne(new LambdaQueryWrapper<SysRole>()
                    .eq(SysRole::getCode, admin.getRole()));
            if (role != null) {
                vo.setRoleName(role.getName());
            }

            return vo;
        }).collect(Collectors.toList()));

        return voPage;
    }

    @Override
    public SysAdmin getAdminById(Long id) {
        return getById(id);
    }

    @Override
    public void updatePassword(Long id, String oldPassword, String newPassword) {
        // 获取当前登录用户ID
        String currentUserId = StpUtil.getLoginIdAsString();

        // 获取管理员信息
        SysAdmin admin = getById(id);
        if (admin == null) {
            throw new BizException("管理员不存在");
        }

        // 如果是修改自己的密码，需要验证旧密码
        if (currentUserId.equals(id)) {
            if (!admin.getPassword().equals(SaSecureUtil.md5(oldPassword))) {
                throw new BizException("旧密码错误");
            }
        }

        // 更新密码
        admin.setPassword(SaSecureUtil.md5(newPassword));
        updateById(admin);
    }
    
    /**
     * 根据角色编码获取角色ID
     *
     * @param roleCode 角色编码
     * @return 角色ID
     */
    private Long getRoleIdByCode(String roleCode) {
        SysRole role = sysRoleMapper.selectOne(
            new LambdaQueryWrapper<SysRole>()
                .eq(SysRole::getCode, roleCode));
        return role != null ? role.getId() : null;
    }
}